import { readFileSync } from "node:fs";
import AppVo from "../model/AppVo";
import BookVo from "../model/BookVo";
import path = require("node:path");
import Utils from "../utils/Utils";
import * as vscode from 'vscode';
import LocalStore from "../utils/LocalStore";
import Setting from "../config/Setting";

export default class AppMgr {
    static init() {
        this.bookVo = new BookVo();

        this.appVo = new AppVo();

        // let _app = readFileSync(path.join(Utils.root, "./res/app_data.json"));
        // let _data = LocalStore.getAll();
        this.appVo.initData();

        this._isStart = false;
        this._isHide = false;
        this._startIndex = 0;
        // this._endIndex = 0;
    }

    private static bookVo: BookVo;
    private static appVo: AppVo;
    static _isStart: boolean = false;
    static _isHide: boolean = false;
    private static _startIndex: number;
    // private _endIndex: number;

    public static initBook(path: vscode.Uri) {
        let _book = readFileSync(path.fsPath);
        this.bookVo.initData({
            content: _book.toString(),
            key: path.path
        });

        const _BK = this.bookVo.key;
        if (this.appVo.auto[_BK]) {
            this._startIndex = this.appVo.auto[_BK].charIndex;
            // this._endIndex = this._startIndex;
        }
    }

    public static getCurPageData(line: number) {
        let _strArr = [];
        let _ind = this._startIndex;
        let _lineStr = "";
        let _isOver = Boolean(this.bookVo.content.length <= _ind);

        const _line = line || Setting.pageLine;

        while (!_isOver && _strArr.length < _line) {
            _isOver = Boolean(this.bookVo.content.length <= _ind);
            const _s = this.bookVo.content[_ind];
            
            _ind++;

            if (_isOver) {
                _strArr.push(_lineStr + "【全书完】");
                break;
            }

            if (_s === "\n") {
                _strArr.push(_lineStr);
                _lineStr = "";
                continue;
            }

            _lineStr += _s;

            if (_lineStr.length === Setting.lineChar) {
                _strArr.push(_lineStr);
                _lineStr = "";
            }
        }

        return {content: _strArr, begin: this._startIndex, end: _ind, isOver: _isOver};
    }
    
    public static setToNextPage(line: number): boolean {
        if (this._startIndex >= this.bookVo.content.length) {return true;}

        const _line = line || Setting.pageLine;

        let _ind = this._startIndex;
        let _isOver = this.bookVo.content.length <= _ind;
        let _lineNum = Utils.getTextLine(this.bookVo.content.substring(this._startIndex, _ind), Setting.lineChar);

        while (!_isOver && _lineNum < _line + 1) {
            _ind++;
            _isOver = this.bookVo.content.length <= _ind;
            _lineNum = Utils.getTextLine(this.bookVo.content.substring(this._startIndex, _ind), Setting.lineChar);
        }

        this._startIndex = _ind;
        return _isOver;
    }

    public static setToLastPage(line: number): boolean {
        if (this._startIndex <= 0) {return true;}

        const _line = line || Setting.pageLine;

        let _ind = this._startIndex;
        let _isOver = _ind <= 0;
        let _lineNum = Utils.getTextLine(this.bookVo.content.substring(_ind, this._startIndex), Setting.lineChar);

        while (!_isOver && _lineNum < _line + 1) {
            _ind--;
            _isOver = _ind <= 0;
            _lineNum = Utils.getTextLine(this.bookVo.content.substring(_ind, this._startIndex), Setting.lineChar);
        }

        this._startIndex = _ind;
        return _isOver;
    }

    public static updateAutoMark() {
        const _BK = this.bookVo.key;
        if (this.appVo.auto[_BK]) {
            this.appVo.auto[_BK].charIndex = this._startIndex;
            // this._endIndex = this._startIndex;
        }
        else {
            this.appVo.auto[_BK] = {charIndex: this._startIndex};
        }

        // this.appVo.asyncJson();
        LocalStore.set("auto", JSON.stringify(this.appVo.auto));
    }

    public static setLineChar(num: number) {
        if (Setting.lineChar === num) {
            return;
        }
        Setting.lineChar = num;
    }

    public static setPageLine(num: number) {
        if (Setting.pageLine === num) {
            return;
        }
        Setting.pageLine = num;
    }

    public static jumpToIndex(n: number) {
        if (n < 0) {n = 0;}
        this._startIndex = Math.min(n, this.bookVo.content.length - Setting.lineChar);
    }

    public static jumpToMatch(str: string) {
        const _ind = this.bookVo.content.indexOf(str);
        if (_ind >= 0) {
            this.jumpToIndex(_ind);
        }
    }

    public static destory() {}
}